package com.ali.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Security配置类
 * EnableWebSecurity：开启Security自定义配置
 */
@EnableWebSecurity
@Configuration
public class WebSecurityConfig {
    /**
     * 内存用户管理器
     */
    @Bean
    public UserDetailsService userDetailsService() {
        //基于内存的用户管理器
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        //创建密码编码器
        PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        //创建用户
        UserDetails userDetails = User.withUsername("admin").password("hello").passwordEncoder(passwordEncoder::encode).build();
        //管理用户
        manager.createUser(userDetails);
        return manager;
    }

    /**
     * 默认配置
     */
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //授权
        http.authorizeHttpRequests(
                authorize -> authorize
                        //对所有请求开启授权保护
                        .anyRequest()
                        //已认证的请求会自动授权
                        .authenticated()
        );

        //登录，表单授权方式
        http.formLogin(form -> form
                //自定义登录页
                .loginPage("/login")
                //无需认证即可访问
                .permitAll()
                //用户登录成功处理器
                .successHandler(new MyAuthenticationSuccessHandler())
        );

        //增加过滤器
        //在用户密码授权过滤器前增加Jwt过滤器
        http.addFilterBefore(new JWTFilter(), UsernamePasswordAuthenticationFilter.class);

        //关闭csrf攻击防御
        http.csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }
}
